<template>
  <div class="flex-col main">
    <div class="flex-col" style="height: 100%;overflow-y:auto;overflow-x:hidden;padding: 10px">
      <div class="flex-row justify-center" style="height: 40px;">
        <!-- 纸张大小 A3、A4 等 -->
        <div class="paper">
          <button v-for="(value, type) in paperTypes" :key="type" :class="curPaperType === type ? 'api' : 'info'"
            @click="setPaper(type, value)">
            {{ type }}
          </button>
          <!-- 自定义纸张 v-show="paperPopVisible"-->
          <div style="display: inline-block">
            <el-popover placement="bottom" width="300" trigger="click">
              <div style="display: inline-block;">
                <input v-model="paperWidth" class="input" style="width: 120px;height: 30px" type="number"
                  placeholder="宽(mm)">
                <span class="ml-10 mr-10">x</span>
                <input v-model="paperHeight" class="input" style="width: 120px;height: 30px" type="number"
                  placeholder="高(mm)">
              </div>
              <div>
                <button class="primary circle-10" style="margin-top: 6px;width: 100%"
                  @click.stop="setPaperOther">确定</button>
              </div>
              <el-button slot="reference" style="height: 41px;">自定义</el-button>
            </el-popover>
          </div>
        </div>
        <!-- 缩放 -->
        <div class="flex-row align-center ml-10">
          <button class="info circle-10" @click="changeScale(false)"><i class="iconfont sv-zoom-out" /></button>
          <div style="margin: 0 4px; width: 40px">{{ (scaleValue * 100).toFixed(0) }}%</div>
          <button class="info circle-10" @click="changeScale(true)"><i class="iconfont sv-zoom-in" /></button>
        </div>
        <button class="api circle-10 ml-10" @click.stop="rotatePaper">
          <i class="iconfont sv-rotate" />
          旋转
        </button>
        <!--   打印 -- panelPrint 预览 -- panelPreview   -->
        <button class="secondary circle-10 ml-10" @click.stop="panelPreview">
          <i class="iconfont sv-printer" />
          预览
        </button>
        <!--   打印 -- panelPrint 预览 -- panelPreview   -->
        <button class="secondary circle-10 ml-10" @click.stop="print">
          <i class="iconfont sv-printer" />
          打印
        </button>
        <!--   打印 -- panelPrint 预览 -- panelPreview   -->
        <button class="secondary circle-10 ml-10" @click.stop="generatePdfStream">
          <i class="iconfont sv-printer" />
          下载PDF
        </button>
        <button class="secondary circle-10 ml-10" @click.stop="savePanel">
          保存模板
        </button>
      </div>

      <div style="text-align: center">
        <!-- 多面板的容器 -->
        <div class="hiprint-printPagination" style="margin-top: 14px;" />
      </div>

      <div class="flex-row" style="height: 87vh">
        <div class="flex-2 left">
          <div class="flex-row justify-center flex-wrap">
            <div class="title">基础元素</div>
            <div class="ep-draggable-item item" tid="defaultModule.text">
              <i class="iconfont sv-text" />
              <span>文本</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.image">
              <i class="iconfont sv-image" />
              <span>图片</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.longText">
              <i class="iconfont sv-longText" />
              <span>长文</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.emptyTable">
              <i class="iconfont sv-table" />
              <span>表格</span>
            </div>

            <div class="title">provider1 自定义样式</div>

            <div class="ep-draggable-item item" tid="providerModule1.qrcode">
              <i class="iconfont sv-image" />
              <span>二维码</span>
            </div>
            <div class="ep-draggable-item item" tid="providerModule1.barcode">
              <i class="iconfont sv-image" />
              <span>条形码</span>
            </div>
            <div class="ep-draggable-item item" tid="providerModule1.image">
              <i class="iconfont sv-image" />
              <span>图片</span>
            </div>
            <!-- provider1 的容器; 加上 class "rect-printElement-types" 使用默认样式 -->
            <!-- 当然可以 重写 或者 自定义样式 -->
            <div id="provider-container1" class="container rect-printElement-types" />

            <div class="title">辅助元素</div>
            <div class="ep-draggable-item item" tid="defaultModule.hline">
              <i class="iconfont sv-hline" />
              <span>横线</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.vline">
              <i class="iconfont sv-vline" />
              <span>竖线</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.rect">
              <i class="iconfont sv-rect" />
              <span>矩形</span>
            </div>
            <div class="ep-draggable-item item" tid="defaultModule.oval">
              <i class="iconfont sv-oval" />
              <span>圆形</span>
            </div>

          </div>
        </div>
        <div class="flex-5 center">
          <!-- 设计器的 容器 -->
          <div id="hiprint-printTemplate" />
        </div>
        <div class="flex-2 right">
          <!-- 元素参数的 容器 -->
          <div id="PrintElementOptionSetting" />
        </div>
      </div>
    </div>
    <div id="preview_content_design" ref="printTemplate"></div>
  </div>

</template>

<script>
import { hiprint, defaultElementTypeProvider } from "vue-plugin-hiprint";
import fontSize from '../utils/font-size.js'
import scale from '../utils/scale.js'
import { provider1 } from '../utils/printUtils.js'
import printData from '../utils/printData'
import design from '../utils/design.json'
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf'
let $ = require("jquery");
// 当前模板实例对象
let hiprintTemplate
export default {
  name: 'PrintView',
  data() {
    return {
      paperTypes: {
        'A3': {
          width: 420,
          height: 296.6
        },
        'A4': {
          width: 210,
          height: 296.6
        },
        'A5': {
          width: 210,
          height: 147.6
        },
        'B3': {
          width: 500,
          height: 352.6
        },
        'B4': {
          width: 250,
          height: 352.6
        },
        'B5': {
          width: 250,
          height: 175.6
        }
      },
      curPaper: {
        type: 'A4',
        width: 210,
        height: 296.6
      },
      // 自定义纸张
      paperPopVisible: false,
      paperWidth: 210,
      paperHeight: 296,
      // 缩小比例
      scaleValue: 1,
      scaleMax: 5,
      scaleMin: 0.5,
      // 设计面板信息
      panel: design,
    }
  },
  computed: {
    curPaperType() {
      let type = 'other'
      const types = this.paperTypes
      for (const key in types) {
        const item = types[key]
        const { width, height } = this.curPaper
        if (item.width === width && item.height === height) {
          type = key
        }
      }
      return type
    }
  },
  mounted() {
    hiprint.init({
      providers: [defaultElementTypeProvider(), provider1({ config: {} })],
    });
    hiprint.PrintElementTypeManager.buildByHtml($(".ep-draggable-item"));
    this.buildLeftElement()
    this.buildDesigner()
  },
  methods: {
    // 获取文件流
    async generatePdfStream() {
      try {
        const panel = JSON.stringify(hiprintTemplate.getJson() || {})
        const html = hiprintTemplate.getHtml(panel)
        // 获取打印模板的 DOM 元素
        $('#preview_content_design').html(html)
        const printElement = this.$refs.printTemplate;
        console.log(printElement, 'printElement')
        // 使用 html2canvas 将 DOM 元素转换为 canvas
        const canvas = await html2canvas(printElement);
        console.log(canvas, 'canvas')
        // 将 canvas 转换为图片数据
        const imgData = canvas.toDataURL('image/png');

        const pdf = new jsPDF();
        // 创建一个新的 jsPDF 实例

        // 计算图片的宽度和高度，以适应 PDF 页面
        const imgProps = pdf.getImageProperties(imgData);
        const pdfWidth = pdf.internal.pageSize.getWidth();
        const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;

        // 将图片添加到 PDF 中
        pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);

        // 获取 PDF 的文件流
        const pdfBlob = pdf.output('blob');

        // 这里可以根据需求对文件流进行处理，例如上传到服务器
        console.log('PDF 文件流:', pdfBlob);

      } catch (error) {
        console.error('生成 PDF 文件流时出错:', error);
      }
    },
    // 打印
    print() {
      const options = { leftOffset: -1, topOffset: -1 }
      const ext = {
        callback: () => {
          console.log('浏览器打印窗口已打开')
        }
        // styleHandler: () => {
        //   return '<style>.hiprint-printElement-text{color:red !important;}</style>';
        // },
      }
      hiprintTemplate.print(printData, options, ext)
    },
    // 创建设计器
    buildLeftElement() {
      hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'))
    },
    // 初始化页面
    buildDesigner() {

      // 还原配置
      hiprint.setConfig()
      // 替换配置
      hiprint.setConfig({
        optionItems: [
          fontSize,
          scale,
          (function () {
            function t() {
              this.name = 'zIndex'
            }

            return t.prototype.css = function (t, e) {
              if (t && t.length) {
                if (e) return t.css('z-index', e)
              }
              return null
            }, t.prototype.createTarget = function () {
              return this.target = $('<div class="hiprint-option-item">\n        <div class="hiprint-option-item-label">\n        元素层级2\n        </div>\n        <div class="hiprint-option-item-field">\n        <input type="number" class="auto-submit"/>\n        </div>\n    </div>'), this.target
            }, t.prototype.getValue = function () {
              var t = this.target.find('input').val()
              if (t) return parseInt(t.toString())
            }, t.prototype.setValue = function (t) {
              this.target.find('input').val(t)
            }, t.prototype.destroy = function () {
              this.target.remove()
            }, t
          }())
        ],
        movingDistance: 2.5,
        text: {
          tabs: [
            // 隐藏部分
            {
              // name: '测试', // tab名称 可忽略
              options: [] // 必须包含 options
            }, // 当修改第二个 tabs 时,必须把他之前的 tabs 都列举出来.
            {
              name: '样式', options: [
                {
                  name: 'scale',
                  after: 'transform', // 自定义参数，插入在 transform 之后
                  hidden: false
                }
              ]
            }
          ],
          supportOptions: [
            {
              name: 'styler',
              hidden: true
            },
            {
              name: 'scale', // 自定义参数，supportOptions 必须得添加
              after: 'transform', // 自定义参数，插入在 transform 之后
              hidden: false
            },
            {
              name: 'formatter',
              hidden: true
            }
          ]
        },
        image: {
          tabs: [
            {
              // 整体替换
              replace: true,
              name: '基本', options: [
                {
                  name: 'field',
                  hidden: false
                },
                {
                  name: 'src',
                  hidden: false
                },
                {
                  name: 'fit',
                  hidden: false
                }
              ]
            }
          ]
        }
      })


      $("#provider-container1").empty(); // 先清空, 避免重复构建
      // eslint-disable-next-line no-undef
      hiprint.PrintElementTypeManager.build($("#provider-container1"), "providerModule1");

      // 构建页面
      hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'))
      // eslint-disable-next-line no-undef
      $("#hiprint-printTemplate").empty(); // 先清空, 避免重复构建
      // 渲染面板
      hiprintTemplate = new hiprint.PrintTemplate({
        template: this.panel, // 模板数据
        settingContainer: '#PrintElementOptionSetting',
        paginationContainer: '.hiprint-printPagination'
      })
      // 构建 并填充到 容器中
      hiprintTemplate.design("#hiprint-printTemplate");
    },
    /**
     * 设置纸张大小
     * @param type [A3, A4, A5, B3, B4, B5, other]
     * @param value {width,height} mm
     */
    setPaper(type, value) {
      try {
        if (Object.keys(this.paperTypes).includes(type)) {
          this.curPaper = { type: type, width: value.width, height: value.height }
          hiprintTemplate.setPaper(value.width, value.height)
        } else {
          this.curPaper = { type: 'other', width: value.width, height: value.height }
          hiprintTemplate.setPaper(value.width, value.height)
        }
      } catch (error) {
        this.$message.error(`操作失败: ${error}`)
      }
    },
    // 设置其它页面
    setPaperOther() {
      const value = {}
      value.width = this.paperWidth
      value.height = this.paperHeight
      this.paperPopVisible = false
      this.setPaper('other', value)
    },
    rotatePaper() {
      if (hiprintTemplate) {
        hiprintTemplate.rotatePaper()
      }
    },
    changeScale(big) {
      let scaleValue = this.scaleValue
      if (big) {
        scaleValue += 0.1
        if (scaleValue > this.scaleMax) scaleValue = 5
      } else {
        scaleValue -= 0.1
        if (scaleValue < this.scaleMin) scaleValue = 0.5
      }
      if (hiprintTemplate) {
        // scaleValue: 放大缩小值, false: 不保存(不传也一样), 如果传 true, 打印时也会放大
        hiprintTemplate.zoom(scaleValue)
        this.scaleValue = scaleValue
      }
    },
    // 保存json
    savePanel() {
      if (hiprintTemplate) {
        const panel = JSON.stringify(hiprintTemplate.getJson() || {})

        console.log(panel, 'panel')
        // updateData({ id: this.tempInfo.id, printPanel: panel }).then(res => {
        //   this.$message({
        //     showClose: true,
        //     type: 'success',
        //     message: this.$t('lang.editSucceeded')
        //   })
        // })



      }
    },

    downPdf() {
      // // 解析模板
      // const hiprintTemplate = new hiprint.PrintTemplate({
      //   template: JSON.parse(temp.printPanel)
      // })
      // // 下载pdf
      // hiprintTemplate.toPdf(data, name)
      // const panel = JSON.stringify(hiprintTemplate.getJson() || {})

      // console.log(panel, 'panel')
      // 创建打印任务
      // console.log(hiprint,'hiprint')
      //  // 创建打印任务
      //  const printTask = hiprint.createPrintTask('printTaskId', {
      //   title: 'My Print Task',
      //   template: {
      //     // 定义打印模板，这里只是一个简单的示例
      //     paperHeader: 'Header',
      //     paperFooter: 'Footer',
      //     paperWidth: 210,
      //     paperHeight: 297,
      //     paperMarginTop: 10,
      //     paperMarginBottom: 10,
      //     paperMarginLeft: 10,
      //     paperMarginRight: 10,
      //     paperDirection: 'portrait',
      //     paperType: 'A4',
      //     content: [
      //       {
      //         type: 'table',
      //         data: [
      //           ['Column 1', 'Column 2'],
      //           ['Data 1', 'Data 2'],
      //           ['Data 3', 'Data 4']
      //         ],
      //         width: '100%',
      //         height: 'auto'
      //       }
      //     ]
      //   }

      // });
      // console.log(printTask,'printTask')
      hiprint.print('pdf', 'test')
    },

  }
}
</script>

<style>
/* 重写全局 hiprint 样式 */
.hiprint-headerLine,
.hiprint-footerLine {
  border-color: red !important;
}

.hiprint-headerLine:hover,
.hiprint-footerLine:hover {
  border-top: 3px dashed red !important;
}

.hiprint-headerLine:hover:before {
  content: "页眉线";
  left: calc(50% - 18px);
  position: relative;
  background: #ffff;
  top: -14px;
  color: red;
  font-size: 12px;
}

.hiprint-footerLine:hover:before {
  content: "页脚线";
  left: calc(50% - 18px);
  position: relative;
  color: red;
  background: #ffff;
  top: -14px;
  font-size: 12px;
}

/* 重写默认的一个样式 */
.rect-printElement-types .hiprint-printElement-type>li>ul>li>a {
  color: red !important;
}

/* 自定义 provider 构建样式 */
.custom-style-types .hiprint-printElement-type {
  display: block;
}

.custom-style-types .hiprint-printElement-type {
  padding: 0 0 0 0;
  list-style: none;
}

.custom-style-types .hiprint-printElement-type>li>.title {
  display: block;
  padding: 4px 0px;
  color: rgb(0, 58, 230);
  clear: both;
}

.custom-style-types .hiprint-printElement-type>li>ul {
  padding: 0 0 0 0;
  display: block;
  list-style: none;
}

.custom-style-types .hiprint-printElement-type>li>ul>li {
  display: block;
  width: 50%;
  float: left;
  max-width: 100px;
}

.custom-style-types .hiprint-printElement-type>li>ul>li>a {
  padding: 12px 6px;
  color: #1296db;
  text-decoration: none;
  background: #fff;
  border: 1px solid #ddd;
  margin-right: 5px;
  width: 95%;
  max-width: 100px;
  display: inline-block;
  text-align: center;
  margin-bottom: 7px;
  box-sizing: border-box;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.15);
}
</style>

<style scoped>
@import '~@/assets/hiprint/css/print.css';

.main {
  padding: 10px;
}

.flex-col {
  display: flex;
  flex-direction: column;
}

/* 区域 */
.left {
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 10px 0;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}

.center {
  margin: 0 10px;
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 20px;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}

.right {
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 10px 0;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}

/* 左侧拖拽元素样式 */
.title {
  font-size: 16px;
  font-weight: 500;
  width: 100%;
  margin: 10px 0 0 24px;
}

.item {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: white;
  padding: 4px 10px;
  margin: 10px 8px 4px 8px;
  width: 38%;
  min-height: 60px;
  border-radius: 4px;
  box-shadow: 2px 2px 2px 2px rgba(171, 171, 171, 0.2);
}

.item .iconfont {
  font-size: 1.5rem;
}

.item span {
  font-size: 14px;
}

/* api按钮 */
.api {
  background: #00acc1;
}

.auto {
  width: auto !important;
}

/* 纸张 */
.paper {
  margin-right: 10px;
}

.paper button:not(class*="auto") {
  width: 60px !important;
}

/* 多个 button 间距 */
.paper button+button {
  margin-left: -1px;
}

.paper button:first-child:last-child {
  border-radius: 4px;
}

/* 两边的 btn 圆角 */
.paper button:first-child:not(:last-child) {
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
}

.paper button:last-child:not(:first-child) {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
}

.popover {
  position: absolute;
  margin-top: 10px;
  z-index: 10;
}

.popover .popover-content {
  background: white;
  border-radius: 4px;
  padding: 10px 14px;
  box-shadow: 2px 2px 2px 4px rgb(128 0 128 / 20%);
}

.popover .input {
  height: 24px;
  padding: 2px 4px;
}

.popover .input:hover {
  border-color: rgb(245, 155, 241);
  border-radius: 4px;
}

/* 区域 */
.left {
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}

.left .container {
  height: 50%;
  overflow: auto;
  padding: 0 10%;
  background: rgb(245, 155, 241);
}

.left .container[id*="provider-container2"] {
  margin-bottom: 10px;
  background: rgb(209, 120, 239);
}

.center {
  margin: 0 10px;
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 20px;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}

.right {
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 10px 0;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}

/* 左侧拖拽元素样式 */
.title {
  font-size: 16px;
  font-weight: 500;
  margin: 4px 0 4px 10px;
}

.item {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: white;
  padding: 4px 10px;
  margin: 10px 8px 4px 8px;
  width: 38%;
  min-height: 60px;
  border-radius: 4px;
  box-shadow: 2px 2px 2px 2px rgba(171, 171, 171, 0.2);
}

.item .iconfont {
  font-size: 1.5rem;
}

.item span {
  font-size: 14px;
}
</style>
